/* vccd/include/vcc/vccd.h 
 * 
 * This file is part of vccd. 
 * 
 * vccd is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version. 
 * 
 * vccd is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details. 
 * 
 * You should have received a copy of the GNU General Public License 
 * along with vccd. If not, see <https://www.gnu.org/licenses/>
 */ 




#ifndef __VCC_VCCD_H
#define __VCC_VCCD_H

#include <stdio.h>
#include <arpa/inet.h>
#include <vcc/vcc.h>
#include <sys/times.h>
#include <klist.h>

#define vcc_log(msg, ...) 	fprintf(stderr, "[%ld] " msg, times(NULL), ##__VA_ARGS__)
#define vcc_info(msg, ...) 	dprintf(infofd, "info [%ld] " msg, times(NULL), ##__VA_ARGS__)

#define LJEST_LEVEL 	16
#define NBEST_LEVEL 	0

#define MIN_LEVEL 	LJEST_LEVEL
#define BEST_LEVEL 	NBEST_LEVEL

struct user {
	/* they're interesting, aren't them? :-) */
	int 		score;
	int 		level;

	char 		username[USRNAME_SIZE];
	char 		passwd[PASSWD_SIZE];
}
/* we don't need __attribute__((packed)), this struct is local.*/
;


void *__amalloc(int nbytes, const char *);
int afree(void *, int nbytes);
int amalloc_report(char *s);

#define amalloc(n) 		__amalloc(n, __FUNCTION__)

int vcc_new_connection(int fd, struct in_addr *addr);
int vcc_close_connection(int fd);

int vcc_write_all(void);
int vcc_write_packages(int fd);
int vcc_new_msg(int fd, struct vcc_request *buf);
int vcc_send_req(struct klist_node *, void *);
int vcc_message_broadcast(char *msg, char *usr, int except_fd, int flags);

int do_user_login(int fd, struct vcc_request *buf);
int do_ia_login(int fd, struct vcc_request *req);
int do_user_logout(int fd);
int init_user_info(int fd, char *usrname, struct user *u);

int create_session(int fd, char *name);
int session_broadcast(int sid, char *msg, char *usr, int except_fd, int flags);
int send_sessions(int fd);
int join_session(int sid, int fd);
int quit_session(int sid, int fd);
int quit_all_session(int fd);
int session_name(int fd, struct vcc_request *req);

int get_user_info(int fd, struct vcc_request *);
int incr_score(int fd, struct vcc_request *);
int monitor_info(int fd, struct vcc_request *);

int relay_new_msg(int fd, void *);
int send_to(int fd, const char *restrict msg, int is_only_visible, const struct vcc_relay_header *restrict hdr, 
		int size);

static inline int relay_send_msg(int fd, const char *restrict msg, const char *restrict usrname) {
	struct vcc_relay_header hdr;

	strcpy(hdr.usrname, usrname);
	return send_to(fd, msg, 1, &hdr, strlen(msg));
}

int relay_broadcast(const char *restrict msg, int expect, 
		const struct vcc_relay_header *restrict hdr);
int relay_send_to(const char *restrict msg, const char *restrict visible, int expect_fd, 
		const struct vcc_relay_header *restrict hdr);
int relay_send_packet(int fd, const char *restrict msg, const struct vcc_relay_header *restrict hdr, int size);
int read_until(int fd, void *, int);

struct klist_node *find_connection(int fd);
extern int infofd;

#endif

